<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"><meta name="author" content="Longlongyu"><meta name="renderer" content="webkit"><meta name="copyright" content="Longlongyu"><meta name="keywords" content="Longlongyu的个人站"><meta name="description" content="null"><meta name="Cache-Control" content="no-cache"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><title>使用Express来开发项目 · Mr.Long's Blog</title><link rel="stylesheet" href="/css/style.css?v=2018.7.9"><link rel="stylesheet" href="/css/animation.css?v=2018.7.9"><link rel="icon" href="/img/assets/favicon.ico"><link rel="stylesheet" href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css?version=1.5.6"><!-- scripts--><script>(function( w ){
  "use strict";
  // rel=preload support test
  if( !w.loadCSS ){
    w.loadCSS = function(){};
  }
  // define on the loadCSS obj
  var rp = loadCSS.relpreload = {};
  // rel=preload feature support test
  // runs once and returns a function for compat purposes
  rp.support = (function(){
    var ret;
    try {
      ret = w.document.createElement( "link" ).relList.supports( "preload" );
    } catch (e) {
      ret = false;
    }
    return function(){
      return ret;
    };
  })();

  // if preload isn't supported, get an asynchronous load by using a non-matching media attribute
  // then change that media back to its intended value on load
  rp.bindMediaToggle = function( link ){
    // remember existing media attr for ultimate state, or default to 'all'
    var finalMedia = link.media || "all";

    function enableStylesheet(){
      link.media = finalMedia;
    }

    // bind load handlers to enable media
    if( link.addEventListener ){
      link.addEventListener( "load", enableStylesheet );
    } else if( link.attachEvent ){
      link.attachEvent( "onload", enableStylesheet );
    }

    // Set rel and non-applicable media type to start an async request
    // note: timeout allows this to happen async to let rendering continue in IE
    setTimeout(function(){
      link.rel = "stylesheet";
      link.media = "only x";
    });
    // also enable media after 3 seconds,
    // which will catch very old browsers (android 2.x, old firefox) that don't support onload on link
    setTimeout( enableStylesheet, 3000 );
  };

  // loop through link elements in DOM
  rp.poly = function(){
    // double check this to prevent external calls from running
    if( rp.support() ){
      return;
    }
    var links = w.document.getElementsByTagName( "link" );
    for( var i = 0; i < links.length; i++ ){
      var link = links[ i ];
      // qualify links to those with rel=preload and as=style attrs
      if( link.rel === "preload" && link.getAttribute( "as" ) === "style" && !link.getAttribute( "data-loadcss" ) ){
        // prevent rerunning on link
        link.setAttribute( "data-loadcss", true );
        // bind listeners to toggle media back
        rp.bindMediaToggle( link );
      }
    }
  };

  // if unsupported, run the polyfill
  if( !rp.support() ){
    // run once at least
    rp.poly();

    // rerun poly on an interval until onload
    var run = w.setInterval( rp.poly, 500 );
    if( w.addEventListener ){
      w.addEventListener( "load", function(){
        rp.poly();
        w.clearInterval( run );
      } );
    } else if( w.attachEvent ){
      w.attachEvent( "onload", function(){
        rp.poly();
        w.clearInterval( run );
      } );
    }
  }


  // commonjs
  if( typeof exports !== "undefined" ){
    exports.loadCSS = loadCSS;
  }
  else {
    w.loadCSS = loadCSS;
  }
}( typeof global !== "undefined" ? global : this ) );</script><script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js" defer></script><script src="/js/main.js?v=2018.7.9" defer></script><!-- fancybox--><link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.2.5/jquery.fancybox.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'"><script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.2.5/jquery.fancybox.min.js" defer></script><!-- busuanzi--><script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script></head><body><section class="profile-close" id="cxo-profile"><div class="profile-avatar"><i class="fa fa-caret-left"></i><img src="/img/assets/cat.png"></div><!--.profile-saying
  i.fa.fa-comment
  .saying--><div class="cxo-profile-inner"><div class="profile-name">longlongyu</div><div class="profile-signature">for me</div><div class="friends"><div>FRIENDS</div><span><a href="//github.com/Longlongyu" target="_black">friendA</a></span><span><a href="//github.com/Longlongyu" target="_black">friendB</a></span><span><a href="//github.com/Longlongyu" target="_black">friendC</a></span></div><div class="read-progress"></div></div></section><header id="cxo-intro" style="height: 70vh;background-image: url(/img/intro/index-bg.png);"><nav id="cxo-intro-nav"><section><div class="intro-nav-title"><a href="/">Mr.Long's Blog</a></div><div class="intro-nav-label-box"><a href="/">Home</a><a href="/about/">About</a><a href="/archives/">Archives</a><a href="/tags/">Tags</a></div><i class="fa fa-bars intro-nav-menu"><div class="intro-nav-drop"><a href="/">Home</a><a href="/about/">About</a><a href="/archives/">Archives</a><a href="/tags/">Tags</a></div></i><div class="clear"></div></section></nav><h1 class="post-title">使用Express来开发项目</h1><div class="post-intros"><div class="post-intro-meta"><span class="post-intro-time"><i class="post-intro-calendar fa fa-edit"></i><span>2018-07-06</span></span><span class="post-intro-tags"><a class="intro-tag fa fa-tag" href="javascript:void(0)" date-tags="learn"> learn</a><a class="intro-tag fa fa-tag" href="javascript:void(0)" date-tags="express"> express</a><a class="intro-tag fa fa-tag" href="javascript:void(0)" date-tags="webpack"> webpack</a><a class="intro-tag fa fa-tag" href="javascript:void(0)" date-tags="babel"> babel</a></span></div><div class="post-intro-read"><span> Word count: <span class="post-count">1,303</span> | Reading time: <span class="post-count">5</span>min</span></div></div></header><article class="cxo-up" id="cxo-content-outer"><section id="cxo-content-inner"><article class="article-entry" id="post"><p><strong><em>Express</em></strong> 是一个基于 <strong><em>Node.js</em></strong> 平台的 <strong><em>web</em></strong> 应用开发框架，它提供一系列强大的特性，可以帮助开发者创建各种 <strong><em>web</em></strong> 和移动设备应用。<br>用 <strong><em>Express</em></strong> 框架开发 <strong><em>web</em></strong> 项目可以直接构建整个项目框架并且将前端页面跟后台贯穿起来。</p>
<p>是一款高度包容、快速而极简的 <strong><em>Node.js Web</em></strong> 框架。</p>
<p><img src="https://cdn-images-1.medium.com/max/701/1*EKW3XazCN98jcVrlEP3H8g.png" alt="expressjs"></p>
<a id="more"></a>
<h1 id="开发环境准备"><a href="#开发环境准备" class="headerlink" title="开发环境准备"></a>开发环境准备</h1><h2 id="安装node-js"><a href="#安装node-js" class="headerlink" title="安装node.js"></a>安装node.js</h2><p><strong><em>Express</em></strong> 是基于 <strong><em>Node.js</em></strong> 的，所以 <strong><em>Node.js</em></strong> 的安装必不可少，不过因为之前通过 <strong><em>hexo</em></strong> 来架构博客的原因，我的电脑已经安装了。</p>
<p><img src="/img/assets/nodejs.png" alt="nodejs"></p>
<h2 id="用npm安装express"><a href="#用npm安装express" class="headerlink" title="用npm安装express"></a>用npm安装express</h2><p><strong><em>npm</em></strong> 是随同 <strong><em>Node.js</em></strong> 一起安装的包管理工具，可以用来安装卸载一些 <strong><em>api</em></strong> 包。<br>使用命令行工具<code>$ npm install (要安装的包)</code>进行本地安装，可以加上<code>-g</code>或者<code>--global</code>进行全局安装。<br>这里执行命令<code>$ npm install express</code>就行。</p>
<hr>
<h1 id="构建项目"><a href="#构建项目" class="headerlink" title="构建项目"></a>构建项目</h1><h2 id="使用express来新建项目框架"><a href="#使用express来新建项目框架" class="headerlink" title="使用express来新建项目框架"></a>使用express来新建项目框架</h2><p><code>cd</code>进入想要建项目的文件夹，执行<code>$ express (项目名称)</code>，会在该目录下创建一个新的你所命名的项目工程。<br>这里我执行的是<code>$ express yiyun --pug --css sass</code>，因为我这里使用了 <strong><em>pug</em></strong> 和 <strong><em>sass</em></strong> 来协助项目开发。   </p>
<p><strong>关于项目框架的说明</strong></p>
<blockquote>
<p>/bin: www  文件用于应用启动<br>/public: 静态资源目录：用来放置项目资源文件的<br>/routes: 路由，是项目的控制器，不过我对其了解不太深，是学习的重点之一<br>/views: view(视图)目录，用来放置前端页面的样式<br>app.js：程序的主文件夹，目前项目中有用到的就是添加新的页面以及页面相应的路由需要在这里配置<br>package.json：项目中用到的一些包的版本信息</p>
</blockquote>
<h2 id="试运行项目"><a href="#试运行项目" class="headerlink" title="试运行项目"></a>试运行项目</h2><p>项目创建好了之后，用命令行进入项目根目录，然后用<code>npm i</code>命令会安装 <strong><em>package.json</em></strong> 中的依赖项目。<br>通过执行<code>$ npm start</code>启动项目，到浏览器输入：<strong><em>localhost:3000</em></strong>，看到 <strong><em>Express</em></strong> 说明成功运行。</p>
<hr>
<h1 id="更好的开发体验"><a href="#更好的开发体验" class="headerlink" title="更好的开发体验"></a>更好的开发体验</h1><p>在编写项目的过程中，对代码进行调试时，每次调试时都需要关闭服务器才能进行重新刷新页面。<br>可以说对开发有着极大的不便，我们需要一些工具来让帮助我们有更好的开发体验。</p>
<h2 id="Express的debug模块"><a href="#Express的debug模块" class="headerlink" title="Express的debug模块"></a>Express的debug模块</h2><p>命令行输入<code>$ DEBUG=(项目名称):* npm start</code>就能执行 <strong><em>express</em></strong> 的 <strong><em>debug</em></strong> 模块。</p>
<h2 id="使用babel来写ES6"><a href="#使用babel来写ES6" class="headerlink" title="使用babel来写ES6"></a>使用babel来写ES6</h2><p>我在编写项目的 <strong><em>javascript</em></strong> 时，使用了 <strong><em>ES6</em></strong> 标准来撰写代码，但是目前的浏览器不支持大多的 <strong><em>ES6</em></strong> 标准，<br>这时候需要一款工具 <strong><em>babel</em></strong> 来帮助我们，<strong><em>babel</em></strong> 可以将 <strong><em>ES6</em></strong> 的代码转换为 <strong><em>ES5</em></strong> 标准，在当下 <strong><em>ES6</em></strong> 还没有在浏览器普及的今天，这可是大利器。</p>
<p>执行<code>$ npm install -g --save-dev babel-cli babel-core babel-plugin-transform-runtime babel-preset-es2015</code><br><strong><em>babel</em></strong> 已经在我们的项目中创建好了，这里的参数<code>--save-dev</code>会将所下载的工具保存到 <strong><em>package.json</em></strong> 的依赖项目中。</p>
<p>新建文件 <strong><em>.babelrc</em></strong> 并且写入</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  &quot;presets&quot;: [&quot;es2015&quot;]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>根据需求在命令行输入指令</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span> 转码结果输出到标准输出</span><br><span class="line"><span class="meta">$</span> babel example.js</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span> 转码结果写入一个文件</span><br><span class="line"><span class="meta">#</span> --out-file 或 -o 参数指定输出文件</span><br><span class="line"><span class="meta">$</span> babel example.js --out-file compiled.js</span><br><span class="line"><span class="meta">#</span> 或者</span><br><span class="line"><span class="meta">$</span> babel example.js -o compiled.js</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span> 整个目录转码</span><br><span class="line"><span class="meta">#</span> --out-dir 或 -d 参数指定输出目录</span><br><span class="line"><span class="meta">$</span> babel src --out-dir lib</span><br><span class="line"><span class="meta">#</span> 或者</span><br><span class="line"><span class="meta">$</span> babel src -d lib</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span> -s 参数生成source map文件</span><br><span class="line"><span class="meta">$</span> babel src -d lib -s</span><br></pre></td></tr></table></figure>
<p>这样就可以简单地运行 <strong><em>babel</em></strong> 了。</p>
<h2 id="搭配webpack来开发"><a href="#搭配webpack来开发" class="headerlink" title="搭配webpack来开发"></a>搭配webpack来开发</h2><p>虽然可以编写 <strong><em>ES6</em></strong> 的代码了，但开发友好度依然不好，而且在调试的时候依然遇到了问题。   </p>
<p><code>Uncaught ReferenceError: require is not defined</code></p>
<p>再查看一下错误位置，发现出现错误的原因是因为我们使用了 <strong><em>import</em></strong> 和 <strong><em>export</em></strong> ，<strong><em>babel</em></strong> 对其只是进行了翻译，并不会合并代码的内容。所以我们需要另一项工具———— <strong><em>webpack</em></strong>。</p>
<p><strong><em>webpack</em></strong> 是一个模块打包器。<strong><em>webpack</em></strong> 的主要目标是将 <strong><em>JavaScript</em></strong> 文件打包在一起，将打包后的文件用于在浏览器中使用。</p>
<p>并且我们使用了 <strong><em>babel</em></strong> ，需要使用 <code>babel-loader</code> 来更好协助打包。</p>
<p>了解用途后，来命令行执行<code>$ npm install -g --save-dev webpack webpack-cli babel-loader</code></p>
<p>新建<code>webpack.config.js</code>文件，并对其进行配置   </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> path = <span class="built_in">require</span>(<span class="string">'path'</span>)</span><br><span class="line"><span class="built_in">module</span>.exports = &#123;</span><br><span class="line">  entry : &#123;</span><br><span class="line">	main : <span class="string">'./src/js/main.js'</span></span><br><span class="line">  &#125;,</span><br><span class="line">  output : &#123;</span><br><span class="line">	<span class="comment">//__dirname，就是当前webpack.config.js文件所在的绝对路径</span></span><br><span class="line">	filename : <span class="string">'[name].js'</span>,</span><br><span class="line">	path : path.join(__dirname, <span class="string">'./public/javascripts'</span>),</span><br><span class="line">  &#125;,</span><br><span class="line">  mode:<span class="string">"development"</span>,</span><br><span class="line">  <span class="built_in">module</span>: &#123;</span><br><span class="line">    rules: [</span><br><span class="line">      &#123;</span><br><span class="line">	  test: <span class="regexp">/\.js$/</span>,</span><br><span class="line">	  loader: <span class="string">'babel-loader'</span>,</span><br><span class="line">	  exclude: <span class="regexp">/node_modules/</span>,</span><br><span class="line">	  query: &#123;</span><br><span class="line">		<span class="string">'presets'</span>: [<span class="string">'es2015'</span>],</span><br><span class="line">		plugins : [<span class="string">'transform-runtime'</span>]</span><br><span class="line">	  &#125;</span><br><span class="line">	&#125;</span><br><span class="line">	]</span><br><span class="line">   &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>最后在 <strong><em>package.json</em></strong> 里编辑命令</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">"scripts"</span>: &#123;</span><br><span class="line">  <span class="string">"dev"</span>: <span class="string">"webpack -w"</span>,</span><br><span class="line">  <span class="string">"start"</span>: <span class="string">"node ./bin/www"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>大功告成，另开一个命令行，分别执行<code>$ npm run dev</code>和<code>$ DEBUG=yiyun:* npm start</code>，现在 <strong><em>webpack</em></strong> 会监视 <strong><em>js</em></strong> 的改动，并重新发布成 <strong><em>main.js</em></strong>，代码修改后只需要刷新浏览器就可以进行调试了。</p>
</article><!-- lincense--><div class="license-wrapper"><p> <span>Author:  </span><a href="https://longlongyu.github.io">Longlongyu</a></p><p> <span>Link:  </span><a href="https://longlongyu.github.io/2018/06/28/Exercise/">https://longlongyu.github.io/2018/06/28/Exercise/</a></p><p> <span>Copyright:  </span><span>All articles in this blog are licensed under <a rel="license" href="https://creativecommons.org/licenses/by-nc-nd/3.0">CC BY-NC-SA 3.0</a> unless stating additionally.</span></p></div><div class="post-paginator"><a class="prevSlogan" href="/2018/07/18/hexoThemeCxo/" title="hexo-theme-Cxo"><span>< PreviousPost</span><br><span class="prevTitle">hexo-theme-Cxo</span></a><a class="nextSlogan" href="/2018/06/20/HelloWorld/" title="Hello-Hexo!"><span>NextPost ></span><br><span class="nextTitle">Hello-Hexo!</span></a><div class="clear"></div></div><div id="comment"><div id="container"></div><link rel="stylesheet" href="https://imsun.github.io/gitment/style/default.css"><script src="https://imsun.github.io/gitment/dist/gitment.browser.js"></script><script>var gitment = new Gitment({
  id: '使用Express来开发项目',
  owner: 'Longlongyu',
  repo: 'Longlongyu.github.io',
  oauth: {
    client_id: 'b91980745918e1925d19',
    client_secret: '44b9dc4da15490c0ce1a46da16b8133973f86af9',
  },
})
gitment.render('container')</script></div></section></article><footer id="cxo-footer-outer"><div id="cxo-footer-inner"><p class="footer-container"><span>Site by </span><a href="http://hexo.io"><span>Hexo</span></a><span> | theme </span><a href="https://github.com/Longlongyu/hexo-theme-Cxo"><span>Cxo</span></a></p><i class="fa fa-user"> </i><span id="busuanzi_value_site_uv"></span><span> | </span><i class="fa fa-eye"> </i><span id="busuanzi_value_site_pv"></span><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?" + 'a4e8b5d92c2afb6bc6f100c10f1988d3';
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();</script></div></footer><!-- catelog--><div class="toc-wrapper" style="top: 70vh;"><div class="toc-catalog"><i class="fa fa-list"> </i><span>CATALOG</span></div><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#开发环境准备"><span class="toc-number">1.</span> <span class="toc-text">开发环境准备</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#安装node-js"><span class="toc-number">1.1.</span> <span class="toc-text">安装node.js</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#用npm安装express"><span class="toc-number">1.2.</span> <span class="toc-text">用npm安装express</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#构建项目"><span class="toc-number">2.</span> <span class="toc-text">构建项目</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#使用express来新建项目框架"><span class="toc-number">2.1.</span> <span class="toc-text">使用express来新建项目框架</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#试运行项目"><span class="toc-number">2.2.</span> <span class="toc-text">试运行项目</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#更好的开发体验"><span class="toc-number">3.</span> <span class="toc-text">更好的开发体验</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Express的debug模块"><span class="toc-number">3.1.</span> <span class="toc-text">Express的debug模块</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#使用babel来写ES6"><span class="toc-number">3.2.</span> <span class="toc-text">使用babel来写ES6</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#搭配webpack来开发"><span class="toc-number">3.3.</span> <span class="toc-text">搭配webpack来开发</span></a></li></ol></li></ol></div><!-- top--><i class="fa fa-arrow-up close" id="go-up" aria-hidden="true"></i></body></html>